"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

"""
"""
Case Type   : 资源池化
Case Name   : 资源池化场景下, 开启共享磁盘锁参数进行备节点failover操作
Create At   : 2024-11-29
Owner       : chenzhikai
Description :
    1. 查看集群状态; expect: 集群状态正常
    2. 设置share_disk_lock_type参数为1;
    3. 重启集群;
    4. 主节点进行failover操作
    5. 再次查看集群状态
    6. 启动集群
    7. 查看集群状态
    8. 停止集群;
    9. 原节点进行节点启动;  
    10. 设置share_disk_lock_type参数为0;
    11. 设置DSS配置为CLUSTER_RAID;
    12. 集群启动成功，集群状态正常
    13. 查看参数值，为初始状态
    14. 恢复环境为初始集群状态：1节点为主节点，2节点为备节点，3节点为备节点
Expect      :
    1. 集群状态正常
    2. 参数设置成功
    3. 重启成功，集群状态正常
    4. 参数设置成功
    5. 原主节点down，备节点升为新主节点
    6. 集群状态Degrade
    7. 集群启动成功
    8. 集群状态正常，原主节点为新备节点，原备节点为新主节点
    9. 设置share_disk_lock_type参数为0
    10. 设置DSS配置为CLUSTER_RAID
    11. 参数设置成功
    12. 集群启动成功，集群状态正常
    13. 查看参数值，为初始状态
    14. 恢复环境为初始集群状态：1节点为主节点，2节点为备节点，3节点为备节点
History     :
    1. 2024-11-29 创建
"""

import os
import unittest
import time
import re

from yat.test import Node
from testcase.utils.ComThread import ComThread
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import macro

Primary_SH = CommonSH('PrimaryDbUser')
Primary_ROOTSH = CommonSH('PrimaryRoot')
Standby1_SH = CommonSH('Standby1DbUser')
Standby2_SH = CommonSH('Standby2DbUser')

@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.com = Common()

        self.s1_comsh = CommonSH('Standby1DbUser')
        self.s2_comsh = CommonSH('Standby2DbUser')
        self.common = Common('Standby1DbUser')

        # 检查集群状态
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        if "can't connect to cm_server" in status:
            # 如果无法连接到cm_server，尝试停止并重启集群
            stopdn = Primary_SH.exec_cm_ctl('stop')
            self.log.info(stopdn)
            status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
            startdn = Primary_SH.exec_cm_ctl('start')
            self.log.info(startdn)
            self.assertIn(self.constant.cm_start_success_msg, startdn, '拉起集群失败')
            status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
            self.log.info(status)
        else:
            self.log.info(status + "集群状态正常")

        # 设置share_disk_lock_type参数
        status = Primary_SH.exec_cm_ctl(mode='set', param='--param --server -k share_disk_lock_type=1')
        self.log.info(status)
        text = '-----step1:设置share_disk_lock_type参数为1; expect:执行成功-----'
        self.log.info(text)
        
        setDSScfg = Primary_SH.exec_cmd_under_user("cd $DSS_HOME/cfg;sed -i 's/^STORAGE_MODE=SHARE_DISK/STORAGE_MODE=CLUSTER_RAID/' dss_inst.ini")
        self.log.info(setDSScfg)
        setDSScfg = Standby1_SH.exec_cmd_under_user("cd $DSS_HOME/cfg;sed -i 's/^STORAGE_MODE=SHARE_DISK/STORAGE_MODE=CLUSTER_RAID/' dss_inst.ini")
        self.log.info(setDSScfg)
        setDSScfg = Standby2_SH.exec_cmd_under_user("cd $DSS_HOME/cfg;sed -i 's/^STORAGE_MODE=SHARE_DISK/STORAGE_MODE=CLUSTER_RAID/' dss_inst.ini")
        self.log.info(setDSScfg)

    def test_shared_storage(self):
        text = '-----step2:查看集群状态; expect:集群状态正常-----'
        self.log.info(text)

        # 查看集群状态
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step3:重启; expect:执行成功-----'
        self.log.info(text)
        restart_res = self.s1_comsh.restart_db_cluster()
        self.log.info(restart_res)
        self.assertTrue(restart_res, '执行失败' + text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)

        # 检查share_disk_lock_type参数
        status = Primary_SH.exec_cm_ctl(mode='query', param='--param --server | grep share_disk_lock_type')
        self.log.info(status)
        self.assertTrue(all(re.search(r'share_disk_lock_type\s*=\s*1', line) for line in status.splitlines()), '执行失败' + text)

        # 检查STORAGE_MODE参数
        status = Primary_SH.exec_cmd_under_user("dsscmd getcfg -n STORAGE_MODE")
        self.log.info(status)
        self.assertIn('CLUSTER_RAID', status, '执行失败' + text)
        status = Standby1_SH.exec_cmd_under_user("dsscmd getcfg -n STORAGE_MODE")
        self.log.info(status)
        self.assertIn('CLUSTER_RAID', status, '执行失败' + text)
        status = Standby2_SH.exec_cmd_under_user("dsscmd getcfg -n STORAGE_MODE")
        self.log.info(status)
        self.assertIn('CLUSTER_RAID', status, '执行失败' + text)

        text = '-----step4:节点2 failover; expect:成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_failover()
        self.log.info(stopdn)
        time.sleep(40)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        res2 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        res3 = status.splitlines()[-1].split('|')[2].split('6003')[-1]
        self.log.info(res1)
        self.log.info(res2)
        self.log.info(res3)
        self.assertIn('P Down    Manually stopped', res1, '执行失败' + text)
        self.assertTrue('S Primary Normal' in res2 or 'S Standby Normal' in res2, '执行失败' + text)
        self.assertTrue('S Primary Normal' in res3 or 'S Standby Normal' in res3, '执行失败' + text)

        text = '-----step5:查看集群状态; expect:集群状态Degraded-----'
        self.log.info(text)

        # 查看集群状态
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Degraded', status, '执行失败' + text)

        text = '-----step6:原节点进行节点启动; expect:执行成功-----'
        self.log.info(text)
        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn, '拉起dn节点失败')

        text = '-----step7:查看集群状态; expect:状态正常-----'
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        self.log.info(res1)
        self.assertIn('     P Standby Normal ', res1, '执行失败' + text)

        text = '-----step8:集群停止; expect:执行成功-----'
        self.log.info(text)
        stopdn = Primary_SH.exec_cm_ctl('stop')
        self.log.info(stopdn)
        self.assertIn(self.constant.cm_stop_success_msg, stopdn, '停止dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn("can't connect to cm_server", status, '执行失败' + text)
        res1 = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        self.log.info(res1)
        self.assertIn("Maybe cm_server is not running, or timeout expired. Please try again.", res1, '执行失败' + text)

        text = '-----step9:原节点进行节点启动; expect:执行成功-----'
        self.log.info(text)
        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn, '拉起dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

    def tearDown(self):
        # 设置share_disk_lock_type参数
        status = Primary_SH.exec_cm_ctl(mode='set', param='--param --server -k share_disk_lock_type=0')
        self.log.info(status)
        text = '-----step11:设置share_disk_lock_type参数为0; expect:执行成功-----'
        self.log.info(text)

        setDSScfg = Primary_SH.exec_cmd_under_user("cd $DSS_HOME/cfg;sed -i 's/^STORAGE_MODE=CLUSTER_RAID/STORAGE_MODE=SHARE_DISK/' dss_inst.ini")
        self.log.info(setDSScfg)
        setDSScfg = Standby1_SH.exec_cmd_under_user("cd $DSS_HOME/cfg;sed -i 's/^STORAGE_MODE=CLUSTER_RAID/STORAGE_MODE=SHARE_DISK/' dss_inst.ini")
        self.log.info(setDSScfg)
        setDSScfg = Standby2_SH.exec_cmd_under_user("cd $DSS_HOME/cfg;sed -i 's/^STORAGE_MODE=CLUSTER_RAID/STORAGE_MODE=SHARE_DISK/' dss_inst.ini")
        self.log.info(setDSScfg)

        text = '-----step12:重启; expect:执行成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        status = Primary_SH.check_cluster_core_status(status, wait_times=600)
        self.log.info(status)
        restart_res = self.s1_comsh.restart_db_cluster()
        self.assertTrue(restart_res, '执行失败' + text)

        # 停止集群
        stopdn = Primary_SH.exec_cm_ctl('stop')
        self.log.info(stopdn)
        self.assertIn(self.constant.cm_stop_success_msg, stopdn, '停止dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn("can't connect to cm_server", status, '执行失败' + text)

        # 启动集群
        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn, '拉起dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step11:恢复环境为初始集群状态; expect:成功-----'
        self.log.info(text)
        recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.log.info(recovery)
        self.assertIn(self.constant.cm_switchover_success_msg, recovery, '执行失败' + text)

        # 查看集群状态
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('P Primary Normal', status.splitlines()[-1].split('|')[0].split('6001')[-1], '执行失败' + text)
        self.assertIn('S Standby Normal', status.splitlines()[-1].split('|')[1].split('6002')[-1], '执行失败' + text)
        self.assertIn('S Standby Normal', status.splitlines()[-1].split('|')[2].split('6003')[-1], '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')